using Xunit;

namespace LeetCodeQuestionBank.Algorithm
{
    public class No0115_NumDistinct
    {
        /*
        给定一个字符串 s 和一个字符串 t ，计算在 s 的子序列中 t 出现的个数。
        字符串的一个 子序列 是指，通过删除一些（也可以不删除）字符且不干扰剩余字符相对位置所组成的新字符串。（例如，"ACE" 是 "ABCDE" 的一个子序列，而 "AEC" 不是）
        题目数据保证答案符合 32 位带符号整数范围。
        示例 1：
            输入：s = "rabbbit", t = "rabbit"
            输出：3
            解释：
                如下图所示, 有 3 种可以从 s 中得到 "rabbit" 的方案。
                (上箭头符号 ^ 表示选取的字母)
                rabbbit
                ^^^^ ^^
                rabbbit
                ^^ ^^^^
                rabbbit
                ^^^ ^^^
        示例 2：
            输入：s = "babgbag", t = "bag"
            输出：5
            解释：
                如下图所示, 有 5 种可以从 s 中得到 "bag" 的方案。
                (上箭头符号 ^ 表示选取的字母)
                babgbag
                ^^ ^
                babgbag
                ^^    ^
                babgbag
                ^    ^^
                babgbag
                ^  ^^
                babgbag
                    ^^^
        提示：
            0 <= s.length, t.length <= 1000
            s 和 t 由英文字母组成
        */

        [Theory]
        [InlineData("rabbbit", "rabbit", 3)]
        [InlineData("babgbag", "bag", 5)]
        public void NumDistinct_OnExecuteTest(string input_s, string input_t, int output)
        {
            Assert.Equal(output, NumDistinct(input_s, input_t));
        }

        public int NumDistinct(string s, string t)
        {
            int m = s.Length, n = t.Length;
            if (m < n)
            {
                return 0;
            }
            int[,] dp = new int[m + 1, n + 1];
            for (int i = 0; i <= m; i++)
            {
                dp[i, n] = 1;
            }
            for (int i = m - 1; i >= 0; i--)
            {
                char sChar = s[i];
                for (int j = n - 1; j >= 0; j--)
                {
                    char tChar = t[j];
                    if (sChar == tChar)
                    {
                        dp[i, j] = dp[i + 1, j + 1] + dp[i + 1, j];
                    }
                    else
                    {
                        dp[i, j] = dp[i + 1, j];
                    }
                }
            }
            return dp[0, 0];
        }
    }
}
